package org.marverse.util

import scala.collection.jcl.ArrayList

object Util {
  
  def getOrElseUpdate[K, V](map: java.util.Map[K, V], key: K, value: => V): V =
    map synchronized {
      var result = map.get(key)
      if (result == null) {
        result = value
        map.put(key, result)
      }       
      result
    }
  
  trait Traverser[-T, +C] {
	def childrenOf(item: T): Seq[C]
  }

  def findFirst[T, C, R](body: C => Option[R])(item: T)(implicit traverser: Traverser[T, C]): Option[R] = {
    for (child <- traverser.childrenOf(item)) {
      val result = body(child)
      if (result != None)
        return result
    }
    return None
  }
  
  def findAll[T, C, R](body: C => Seq[R])(item: T)(implicit traverser: Traverser[T, C]): Stream[R] = {
    Stream.fromIterator(traverser.childrenOf(item).elements) flatMap(body(_))
  }

  /**
   * Convenience method that calls <code>check(ctx)</code> on all <code>Checkable</code> 
   * children of <code>that</code>. 
   */
  def checkChildren[T, C](that: T, ctx: MutableTypedMap[TypedKey, Any])(implicit traverser: Util.Traverser[T, C]) {
    for (child <- traverser.childrenOf(that)) 
      if (child.isInstanceOf[Checkable]) child.asInstanceOf[Checkable].check(ctx)
  }
  
}
